﻿using System;
using System.Collections.Concurrent;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using HtmlAgilityPack;

class WebCrawler
{
    private HttpClient client = new HttpClient();  // 使用HttpClient来发起网络请求
    private ConcurrentDictionary<string, ConcurrentBag<string>> phoneNumbers = new ConcurrentDictionary<string, ConcurrentBag<string>>();  // 使用线程安全的字典存储每个URL及其找到的电话号码

    // 异步方法，开始爬取操作
    public async Task StartCrawlingAsync(string keyword)
    {
        string searchUrl = $"https://www.google.com/search?q={Uri.EscapeDataString(keyword)}";  // 构造Google搜索的URL ,要开vpn
        var html = await client.GetStringAsync(searchUrl);  // 异步获取搜索结果页面的HTML
        var doc = new HtmlDocument();
        doc.LoadHtml(html);  // 加载HTML内容到HtmlDocument

        var links = doc.DocumentNode.SelectNodes("//a[@href]");  // 从HTML中查找所有带有href属性的<a>标签

        if (links != null)
        {
            var tasks = new List<Task>();  // 创建一个任务列表以并行处理所有链接
            foreach (var link in links)
            {
                string hrefValue = link.GetAttributeValue("href", string.Empty);  // 获取每个链接的href值
                if (hrefValue.StartsWith("http"))  // 确保是完整的URL
                {
                    tasks.Add(Task.Run(() => ExtractPhoneNumbers(hrefValue)));  // 创建一个新的任务来提取电话号码
                }
            }
            await Task.WhenAll(tasks);  // 等待所有任务完成
        }

        // 打印所有收集到的电话号码及其对应的URL
        foreach (var entry in phoneNumbers)
        {
            Console.WriteLine($"URL: {entry.Key}");
            foreach (var number in entry.Value)
            {
                Console.WriteLine($" Phone: {number}");
            }
        }
    }

    // 异步方法，用于从指定的URL中提取电话号码
    private async Task ExtractPhoneNumbers(string url)
    {
        try
        {
            var html = await client.GetStringAsync(url);  // 异步获取页面HTML
            var doc = new HtmlDocument();
            doc.LoadHtml(html);  // 加载HTML内容到HtmlDocument

            // 定义电话号码的正则表达式模式
            var phoneNumberPattern = @"(\d{3}[-.\s]??\d{3}[-.\s]??\d{4}|\d{3}[-.\s]??\d{4})";
            var matches = Regex.Matches(html, phoneNumberPattern);  // 在HTML中搜索匹配的电话号码

            // 将找到的电话号码添加到字典中
            foreach (Match match in matches)
            {
                phoneNumbers.AddOrUpdate(url, new ConcurrentBag<string> { match.Value },
                    (key, oldValue) => { oldValue.Add(match.Value); return oldValue; });
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to process {url}: {ex.Message}");  // 处理失败时打印错误信息
        }
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Enter keyword for search:");  // 提示用户输入搜索关键词
        string keyword = Console.ReadLine();  // 读取用户输入的关键词
        var crawler = new WebCrawler();  // 创建爬虫实例
        await crawler.StartCrawlingAsync(keyword);  // 开始执行爬取操作
    }
}
